﻿/*********************************************************************************/
/**    Sims3Pack Readme Generator                                               **/
/**    Copyright (C) 2012  Anja Knackstedt                                      **/
/**                                                                             **/
/**    This program is free software: you can redistribute it and/or modify     **/
/**    it under the terms of the GNU General Public License as published by     **/
/**    the Free Software Foundation, either version 3 of the License, or        **/
/**    (at your option) any later version.                                      **/
/**                                                                             **/
/**    This program is distributed in the hope that it will be useful,          **/
/**    but WITHOUT ANY WARRANTY; without even the implied warranty of           **/
/**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            **/
/**    GNU General Public License for more details.                             **/
/**                                                                             **/
/**    You should have received a copy of the GNU General Public License        **/
/**    along with this program.  If not, see <http://www.gnu.org/licenses/>.    **/
/**                                                                             **/
/*********************************************************************************/




using System;
using System.Data;
using System.Windows.Forms;
using Sims3PackReadmeGenerator.Sims3PackReader;
using Sims3PackReadmeGenerator.language;

namespace Sims3PackReadmeGenerator.Gui
{
    /// <summary>
    /// form for managing the bad cc information
    /// </summary>
    public partial class ManageBadCCInfoGui : Form
    {
        #region events

        public delegate void ManageBadCCInfoFormEventHandler(object sender, EventArgs e);
        public event ManageBadCCInfoFormEventHandler OnBadCCInfoUpdateHandler;

        protected void OnBadCCInfoUpdate()
        {
            if (OnBadCCInfoUpdateHandler != null)
                OnBadCCInfoUpdateHandler(this, new EventArgs());
        }

        #endregion

        #region fields

        private DataSet _dataSetBadCC;
        private bool    _isDataUpdated = false;
        private bool    _isFormLoading = false;

        #endregion

        #region constructor

        /// <summary>
        /// initializes the form
        /// </summary>
        public ManageBadCCInfoGui()
        {
            InitializeComponent();
        }

        #endregion

        #region methods

        /// <summary>
        /// handles the form load event
        /// reads the bad cc packages information from the xml file
        /// fills the data grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ManageBadCCInfo_Load(object sender, EventArgs e)
        {
            _isFormLoading = true;

            //setup error provider
            errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;

            loadBadCCInfo();

            _isFormLoading = false;
        }

        /// <summary>
        /// loads info from xml to datagrid view
        /// </summary>
        private void loadBadCCInfo()
        {
            _isDataUpdated = false;

            //create data set and table
            _dataSetBadCC = new DataSet();
            _dataSetBadCC.DataSetName = datatableIDs.manageBadCCDataSetName;
            DataTable dataTable = new DataTable(datatableIDs.manageBadCCDataTable);
            dataTable.Columns.Add(datatableIDs.manageBadCCColumnPackageId, typeof(string));
            dataTable.Columns.Add(datatableIDs.manageBadCCColumnName, typeof(string));
            dataTable.Columns.Add(datatableIDs.manageBadCCColumnCategory, typeof(string));

            //package id is primary key
            DataColumn[] keys = new DataColumn[1];
            keys[0] = dataTable.Columns[0];
            dataTable.PrimaryKey = keys;

            _dataSetBadCC.Tables.Add(dataTable);

            //read xml file to dataset
            this.Cursor = Cursors.WaitCursor;
            try
            {
                _dataSetBadCC.ReadXml(FilePaths.badCCXmlDataPath, XmlReadMode.Auto);
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(  errors.errorKnownOrBadCCLoad, ex.Message), 
                                                errors.errorKnownOrBadCCLoadTitle, 
                                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            this.Cursor = Cursors.Default;

            //change column names to gui column names
            _dataSetBadCC.Tables[0].Columns[0].Caption = names.manageBadCCGuiColumnPackageId;
            _dataSetBadCC.Tables[0].Columns[0].ColumnName = names.manageBadCCGuiColumnPackageId;
            _dataSetBadCC.Tables[0].Columns[1].Caption = names.manageBadCCGuiColumnName;
            _dataSetBadCC.Tables[0].Columns[1].ColumnName = names.manageBadCCGuiColumnName;
            _dataSetBadCC.Tables[0].Columns[2].Caption = names.manageBadCCGuiColumnCategory;
            _dataSetBadCC.Tables[0].Columns[2].ColumnName = names.manageBadCCGuiColumnCategory;

            //use the dataset as data source of the data grid
            dataGridViewBadCC.DataSource = _dataSetBadCC.Tables[0];

            dataGridViewBadCC.Columns[0].Width = 220;
            dataGridViewBadCC.Columns[1].Width = 240;
            dataGridViewBadCC.Columns[2].Width = 110;

            fillErrorCatCombobox();
            comboBoxErrorCat.SelectedIndex = 0;
        }

        /// <summary>
        /// saves the info from the datagrid view to xml
        /// </summary>
        private void commitBadCCInfo()
        {
            bool isCommitSuccess = false;
            
            //rename columns for export
            _dataSetBadCC.Tables[0].Columns[0].Caption      = datatableIDs.manageBadCCColumnPackageId;
            _dataSetBadCC.Tables[0].Columns[0].ColumnName   = datatableIDs.manageBadCCColumnPackageId;
            _dataSetBadCC.Tables[0].Columns[1].Caption      = datatableIDs.manageBadCCColumnName;
            _dataSetBadCC.Tables[0].Columns[1].ColumnName   = datatableIDs.manageBadCCColumnName;
            _dataSetBadCC.Tables[0].Columns[2].Caption      = datatableIDs.manageBadCCColumnCategory;
            _dataSetBadCC.Tables[0].Columns[2].ColumnName   = datatableIDs.manageBadCCColumnCategory;


            this.Cursor = Cursors.WaitCursor;
            try
            {
                _dataSetBadCC.WriteXml(FilePaths.badCCXmlDataPath);
                isCommitSuccess = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(errors.errorKnownOrBadCCCommit, ex.Message),
                                     errors.errorKnownOrBadCCCommitTitle,
                                     MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            this.Cursor = Cursors.Default;

            //rename columns for gui
            _dataSetBadCC.Tables[0].Columns[0].Caption = names.manageBadCCGuiColumnPackageId;
            _dataSetBadCC.Tables[0].Columns[0].ColumnName = names.manageBadCCGuiColumnPackageId;
            _dataSetBadCC.Tables[0].Columns[1].Caption = names.manageBadCCGuiColumnName;
            _dataSetBadCC.Tables[0].Columns[1].ColumnName = names.manageBadCCGuiColumnName;
            _dataSetBadCC.Tables[0].Columns[2].Caption = names.manageBadCCGuiColumnCategory;
            _dataSetBadCC.Tables[0].Columns[2].ColumnName = names.manageBadCCGuiColumnCategory;

            dataGridViewBadCC.Columns[0].Width = 220;
            dataGridViewBadCC.Columns[1].Width = 240;
            dataGridViewBadCC.Columns[2].Width = 110;

            if (isCommitSuccess)
            {
                btCommit.Enabled = false;
                _isDataUpdated = true;                
            }
            
        }

        /// <summary>
        /// fills the error category combobox
        /// </summary>
        private void fillErrorCatCombobox()
        {           
            comboBoxErrorCat.Items.Add(names.manageBadCCErrorCatNameCrash);
            comboBoxErrorCat.Items.Add(names.manageBadCCErrorCatNameTxtcError);
            comboBoxErrorCat.Items.Add(names.manageBadCCErrorCatNameTextureErr);
            comboBoxErrorCat.Items.Add(names.manageBadCCErrorCatNameOther);
        }

        /// <summary>
        /// returns id for an error category name
        /// name comes from the ressource file and can be in different languages
        /// when no id for given name exits, the category name is returned
        /// </summary>
        /// <param name="errorCatName">name of the category</param>
        /// <returns>id of the category</returns>
        private string getErrotCatIdFromName(string errorCatName)
        {
            string errorId = errorCatName;

            if (errorCatName == names.manageBadCCErrorCatNameCrash)
            {
                errorId = xmlStringValues.badCCErrorCatIdCrash;
            }
            else if (errorCatName == names.manageBadCCErrorCatNameTxtcError)
            {
                errorId = xmlStringValues.badCCErrorCatIdTxtcError;
            }
            else if (errorCatName == names.manageBadCCErrorCatNameTextureErr)
            {
                errorId = xmlStringValues.badCCErrorCatIdTextureErr;
            }
            else if (errorCatName == names.manageBadCCErrorCatNameOther)
            {
                errorId = xmlStringValues.badCCErrorCatIdOther;
            }

            return errorId;
        }

        /// <summary>
        /// handles the add button click event
        /// adds the values of the input textboxes to the datagrid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btAdd_Click(object sender, EventArgs e)
        {
            if (!validateInput())
                return;
            
            string errorCatId = getErrotCatIdFromName(comboBoxErrorCat.Text);

            try
            {
                _dataSetBadCC.Tables[0].Rows.Add(txtPackageId.Text, txtName.Text, errorCatId);

                //reset input text boxes
                txtName.Text = "";
                txtPackageId.Text = "";
                comboBoxErrorCat.SelectedIndex = 0;
            }
            catch(Exception ex)
            {
                if (ex.GetType() == typeof(ConstraintException))
                {
                    errorProvider.Clear();
                    errorProvider.SetError(txtPackageId, ex.Message);
                }
                else
                {
                    MessageBox.Show(string.Format(errors.errorAddBadCCInfo, ex.Message), errors.errorAddBadCCInfoTitle);
                }
            }

        }

        /// <summary>
        /// checks if all necessary textboxes are filled
        /// </summary>
        /// <returns>true when all necessary textboxes are filled</returns>
        private bool validateInput()
        {
            bool isValid = true;
           
            errorProvider.Clear();     

            if (string.IsNullOrEmpty(txtName.Text))
            {
                errorProvider.SetError(txtName, errors.errorBadCCInfoNameIsEmpty);
                isValid = false;
            }
            if (string.IsNullOrEmpty(txtPackageId.Text))
            {
                errorProvider.SetError(txtPackageId, errors.errorBadCCInfoPackageIdIsEmpty);
                isValid = false;
            }
            return isValid;
        }

        /// <summary>
        /// handles the click event on the commit button
        /// the data set values are written to the xml file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btCommit_Click(object sender, EventArgs e)
        {
            commitBadCCInfo();
        }

        /// <summary>
        /// handles the form closing event
        /// notifies about changed bad cc info
        /// save changes when ok is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ManageBadCCInfo_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_isDataUpdated)
            {
                OnBadCCInfoUpdate();
            }
            else if (this.DialogResult == DialogResult.OK)
            {
                //commit unsaved changes
                if (btCommit.Enabled == true)
                {                    
                        commitBadCCInfo();
                        OnBadCCInfoUpdate();
                }
            }
        }

        /// <summary>
        /// handles the open package button event
        /// opens the chosen sims3pack file and reads the packageId
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btOpenFile_Click(object sender, EventArgs e)
        {
            try
            {
                DialogResult result = openSims3PackDialog.ShowDialog();
                if (result == DialogResult.OK)
                {
                    Sims3PackReaderClass reader = new Sims3PackReaderClass();
                    string packageId, nameDE, nameEN;
                    reader.readPackageIdDisplayNameFromSims3Pack(openSims3PackDialog.FileName,out packageId,out nameDE, out nameEN);

                    txtPackageId.Text = packageId;
                    txtName.Text = nameEN;
                }
            }
            catch (Exception ex)
            {

                MessageBox.Show(    string.Format(errors.errorBadCCInfoOpenFile, ex.Message),
                                    errors.errorBadCCInfoOpenFileTitle,MessageBoxButtons.OK ,
                                    MessageBoxIcon.Error);
            }

        }

        /// <summary>
        /// handles the cell value changed event of the datagrid view
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridViewBadCC_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (!_isFormLoading)
            {
                btCommit.Enabled = true;
            }
        }

        /// <summary>
        /// handles the rows added event of the datagrid view
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridViewBadCC_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            if (!_isFormLoading)
            {
                btCommit.Enabled = true;
            }
        }

        /// <summary>
        /// handles the rows removed event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridViewBadCC_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            if (!_isFormLoading)
            {
                btCommit.Enabled = true;
            }
        }

        #endregion        

       

      
    }
}
